#include "QuadTreeHojas.h"

QuadTreeHojas::QuadTreeHojas():QuadTree() {
	columna = 0;
	fila = 0;
	colorhomo = 0;

}

QuadTreeHojas::~QuadTreeHojas() {

}

bool QuadTreeHojas::agregarDatoHoja(int color) {
	if (!arbol.empty()){
		(*posicion).second = color;
		posicion++;
		return true;
	}
	else
		colorhomo = color;
	return true;
}

bool QuadTreeHojas::agregarDato() {
	if (arbol.empty())
		for (int i = 1; i < 5; i++) {
			pair<vector<int>,int> pairaux;
			pairaux.first.push_back(i);
			arbol.push_back(pairaux);
			posicion = arbol.begin();
		}
	else {
		pair<vector<int>,int> pairaux(*posicion);
		posicion = arbol.erase(posicion);
		for (int i = 4; i >= 1; i--){
			pairaux.first.push_back(i);
			posicion = arbol.insert(posicion,pairaux);
			pairaux.first.pop_back();
		}
	}
	return true;
}

void QuadTreeHojas::irRaiz() {
	columna = 0;
	fila = RAIZ;
}

bool QuadTreeHojas::esHoja() {
	if (fila == RAIZ)
		return false;
	else
		if (arbol.empty() || columna == (arbol[fila].first.size() - 1))
			return true;
		else
			return false;
}

int QuadTreeHojas::getPadre() {
	int aux = 0;
	while (arbol[fila].first[aux] == arbol[fila+1].first[aux] && aux < arbol[fila].first.size()-1 && aux < arbol[fila+1].first.size()-1)
		aux++;
	return aux;
 }

void QuadTreeHojas::irSiguiente() {
	if (columna < arbol[fila].first.size()-1)
		columna++;
	else
		if (arbol[fila].first[arbol[fila].first.size()-1] != 4)
			fila++;
		else {
			columna = getPadre();
			fila++;
		}
}

bool QuadTreeHojas::avanzar(int) {
	if (fila == RAIZ)
		fila = 0;
	else
		irSiguiente();
	return true;

}

long QuadTreeHojas::getDato(){
	if (arbol.empty())
		return colorhomo;
	else
		return (arbol[fila].second);
}

double QuadTreeHojas::concatenar(vector<int> nodo) {
	double aux = 0, diez =10;
	int potmax = nodo.size() - 1;
	for (int j = 0; j < nodo.size(); j++)
		aux += nodo.at(j)*pow(diez,potmax-j);
	return aux;
}

void QuadTreeHojas::mostrar() {
	for (int i = 0; i < arbol.size(); i++) {
		cout << "Arbol en la pos: " << i << endl;
		for (int j = 0; j < arbol[i].first.size(); j++)
			cout << arbol[i].first.at(j) << " ";
		cout<<" El color es: "<<arbol[i].second<<" ";
		cout << endl;
	}
}

void QuadTreeHojas::setnodo(double nodo, int dato) {
	double aux = 0;
	int modulo = 0;
	pair<vector<int>,int > pairaux;
	aux = nodo;
	while (aux >= 1) {
		modulo = fmod(aux,10);
		pairaux.first.insert(pairaux.first.begin(),modulo);
		aux = aux/10;
	}
	pairaux.second = dato;
	arbol.push_back(pairaux);
	modulo = 0;
	aux = 0;
}

void QuadTreeHojas::guardar(ofstream & salida){
	int tamanio = arbol.size();
	if (tamanio == 0)  //la raiz es una hoja
		salida.write((char *)&colorhomo,sizeof(int));
	else {
		double aux = 0;
		salida.write((char *)&HOJAS,sizeof(int));
		salida.write((char *)&tamanio,sizeof(int));
		for (int i = 0; i < tamanio; i++){
			aux = concatenar(arbol[i].first);
			salida.write((char *)&aux,sizeof(double));
			salida.write((char *)&arbol[i].second,sizeof(int));
        }
	}
}

void QuadTreeHojas::recuperar(ifstream & entrada) {
	int tamanio = 0;
	entrada.read((char *)&tamanio,sizeof(int));
	if (tamanio == 1) {//caso raiz es hoja
		entrada.read((char *)&colorhomo,sizeof(int));
	}
	else {
		double nodo;
		int dato;
		for (int i = 0; i < tamanio; i++) {
			entrada.read((char *)&nodo,sizeof(double));
			entrada.read((char *)&dato,sizeof(int));
			setnodo(nodo,dato);
		}
	}
}
